import json
from Transaction import Transaction
from Crypto_modified import ECDSA
from Crypto.Util.asn1 import DerSequence
from Crypto.Hash import SHA256
import time


'''交易解码'''
def decode(tx):
    tx_dict = json.loads(tx)
    tx_out = Transaction(nonce=tx_dict['nonce'])
    tx_out.type = tx_dict['type']
    tx_out.value = tx_dict['value']
    tx_out.receiveAddress = tx_dict['receiveAddress']
    tx_out.gasPrice = tx_dict['gasPrice']
    tx_out.gas = tx_dict['gas']
    tx_out.data = bytes.fromhex(tx_dict['data'])
    tx_out.chainId = tx_dict['chainId']
    tx_out.groupId = tx_dict['groupId']
    tx_out.extraData = bytes.fromhex(tx_dict['extraData'])
    tx_out.vrs = tx_dict['vrs']
    tx_out.hashWith = tx_dict['hashWith']
    tx_out.sender = tx_dict['sender']
    tx_out.blockLimit = tx_dict['blockLimit']
    tx_out.importTime = tx_dict['importTime']
    return tx_out


'''交易验签'''
def authenticate(tx, tx_signature):
    r = tx_signature[0][1]
    s = tx_signature[0][2]
    der = DerSequence()
    der.append(r)
    der.append(s)
    signature = der.encode()
    return ECDSA.authenticate(SHA256.new(tx.hashWith.encode()), tx_signature[1], signature)


class TxPool:
    def __init__(self):
        self.pool = []
        self.maxLength = 18

    def append(self, tx, tx_signature):
        '''交易缓存'''
        if len(self.pool) > self.maxLength:
            print('Cache full')
            del tx, tx_signature
            return
        tx_decode = decode(tx)
        '''交易去重'''
        for tx_exist in self.pool:
            if tx_decode.nonce == tx_exist.nonce:
                del tx, tx_signature
                print('Duplicate transaction')
                return
        if authenticate(tx_decode, tx_signature):
            tx_decode.importTime = int(time.time() * 10000000)
            self.pool.append(tx_decode)

    '''交易删除'''
    def remove(self,tx):
        self.pool.remove(tx)